package com.shh.aiojbackendserver.manager;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shh.aiojbackendserver.model.dto.questionsubmit.QuestionSubmitQueryRequest;
import com.shh.aiojbackendserver.model.entity.QuestionSubmit;
import com.shh.aiojbackendserver.model.entity.User;
import com.shh.aiojbackendserver.model.entity.UserRanking;
import com.shh.aiojbackendserver.model.entity.UserSolvedProblems;
import com.shh.aiojbackendserver.model.enums.JudgeInfoMessageEnum;
import com.shh.aiojbackendserver.model.vo.UserRankingVO;
import com.shh.aiojbackendserver.service.QuestionSubmitService;
import com.shh.aiojbackendserver.service.UserService;
import com.shh.aiojbackendserver.service.UserSolvedProblemsService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBatch;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RScoredSortedSetAsync;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 使用redis有序集合数据结构实现 跟据刷题的数量完成排行榜功能
 */
@Component
@Slf4j
public class LeaderboardManager {

    @Resource
    private UserService userService;

    @Resource
    private UserSolvedProblemsService userSolvedProblemsService;

    @Resource
    private QuestionSubmitService questionSubmitService;

    private static final String LEADERBOARD_KEY = "leaderboard:solved";


    private final RedissonClient redissonClient;

    public LeaderboardManager(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    /**
     * 获取排行榜的 SortedSet 实例
     */
    private RScoredSortedSet<String> getLeaderboard() {
        return redissonClient.getScoredSortedSet(LEADERBOARD_KEY);
    }


    /**
     * 用户解题时更新排行榜
     */
    @Transactional
    public void onProblemSolved(Long userId, Long problemId,boolean isAccepted) {
        // 1. 检查是否通过
        if(isAccepted){
            //再判断是否为第一次通过
            if (isFirstSolved(userId, problemId)) {
                //原子性更新所有排行榜
                //创建一个批量操作对象 RBatch 这个对象允许你将多个Redis命令收集起来，然后一次性发送到服务器执行
                RBatch batch = redissonClient.createBatch();
                RScoredSortedSetAsync<String> totalBoard = batch.getScoredSortedSet(LEADERBOARD_KEY);
                totalBoard.addScoreAsync(userId.toString(), 1);
                //执行批量操作
                batch.execute();
            }
        }
    }

    // 获取前 N 名用户
    /**
     * 获取前N名用户
     */
    public List<UserRankingVO> getTopNUsers(int limit) {
        RScoredSortedSet<String> leaderboard = getLeaderboard();

        // 获取前N名用户ID和分数
        Collection<String> userIds = leaderboard.valueRangeReversed(0, limit - 1);
        int totalSize = leaderboard.size();

        return userIds.stream()
                .map(userIdStr -> {
                    Long userId = Long.parseLong(userIdStr);
                    Double score = leaderboard.getScore(userIdStr);
                    String userName = userService.getById(userId).getUserName();

                    // 获取用户排名（从0开始，所以+1）
                    Integer rank = leaderboard.rank(userIdStr) + 1;
                    Integer reverseRank = totalSize - rank; // 转换为降序排名


                    return new UserRankingVO(
                            userId,
                            userName != null ? userName : "Unknown",
                            score != null ? score.intValue() : 0,
                            reverseRank+1
                    );
                })
                .collect(Collectors.toList());
    }


    /**
     * 判断是否为首次解决题目
     * @param userId
     * @param questionId
     * @return
     */
    public boolean isFirstSolved(long userId,long questionId){
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("problemId",questionId);
        //查用户提交辅表
        boolean exists = userSolvedProblemsService.exists(queryWrapper);
        if(exists){
            return false;
        }else{
            // 2. 记录到数据库
            UserSolvedProblems userSolvedProblems = new UserSolvedProblems();
            userSolvedProblems.setUserId(userId);
            userSolvedProblems.setProblemId(questionId);
            userSolvedProblemsService.save(userSolvedProblems);
            return true;
        }
    }

}
